var Tween = require('geoTweenMoveTo');
/**
 * 主要用于操控ArmatureDisplay
 */
cc.Class({
    extends: cc.Component,

    properties: {
        target: {
            default: null,
            type: dragonBones.ArmatureDisplay,
        },
        tweenMoves: {
            default: [],
            type: [Tween],
            tooltip: '与使该对象产生位移有关的组件'
        },
        labelEvents: {
            default: [],
            type: [cc.Component.EventHandler],
            tooltip: '出现帧标签时调用',
        },
        completeEvents: {
            default: [],
            type: [cc.Component.EventHandler],
            tooltip: '播放完成时调用',
        },
    },

    // LIFE-CYCLE CALLBACKS:

    // onLoad() {
    //     this.target = this.target || this.node.getComponent(dragonBones.ArmatureDisplay);
    // },

    // update (dt) {},
    onEnable() {
        // 监听帧标签，以播放响应的音效
        this.anim().addEventListener(dragonBones.EventObject.FRAME_EVENT, this._frameEventHandler, this);
        this.anim().addEventListener(dragonBones.EventObject.COMPLETE, this._completeEventHandler, this);
    },
    onDisable() {
        // 若动画控制器已经失效，就不作处理了，否则引起空对象异常
        if (this.target.isValid == false)
            return;
        // 解除监听帧标签
        this.anim().removeEventListener(dragonBones.EventObject.FRAME_EVENT, this._frameEventHandler, this);
        this.anim().removeEventListener(dragonBones.EventObject.COMPLETE, this._completeEventHandler, this);
    },
    anim() {
        return this._getTarget();
    },
    armature() {
        return this._getTarget().armature();
    },
    armAnim() {
        return this._getTarget().armature().animation;
    },
    /**
     *  以融合模式播放动画
     * @param {string} animationName 
     * @param {number} fadeInTime 
     * @param {int} playTimes 
     * @param {bool} displayControl 是否动画影像显示对象
     * @param {function} complete 
     */
    fadeInAnim(animationName, fadeInTime, playTimes, complete, displayControl) {
        void 0 === fadeInTime && (fadeInTime = -1);
        void 0 === playTimes && (playTimes = -1);
        var animationState = this.armAnim().fadeIn(animationName, fadeInTime, playTimes, void 0, void 0, void 0, void 0, displayControl);
        if (playTimes > 0 && complete) {
            // var totalTime = animationState.totalTime;
            // if (complete) {
            //     // 加0.1，为防止最后一帧后面的融合动画略过，建议帧事件不要放在最后一帧
            //     this.scheduleOnce(complete, totalTime * playTimes + 0.1);
            // }
            var self = this;
            var completeWrapper = (() => {
                cc.log('complete on: ' + animationName);
                complete();
                self.anim().removeEventListener(dragonBones.EventObject.COMPLETE, completeWrapper);
            });
            self.anim().addEventListener(dragonBones.EventObject.COMPLETE, completeWrapper);
        }
        //
        return animationState;
    },
    /**
     * 暂停当前动画
     */
    pause() {
        this.armAnim().stop();

    },
    /**
     * 恢复当前动画
     */
    resume() {
        this.armAnim().play();
    },
    /**
     * 停止动画播放
     */
    stop(){
        this.armAnim().stop();
    },
    /**
     * 子类可以完全重载
     * @param {string} label 
     */
    onFrameLabel(label) {
        // 这里什么也不做，由子类覆盖实现。
    },
    _completeEventHandler(e) {
        this._onComplete();
    },
    // 监听帧事件
    _frameEventHandler(e) {
        // 发送帧标签事件
        // this.node.emit(dragonBones.EventObject.FRAME_EVENT, e.detail);
        var label = (e.detail != null) ? e.detail.name : e.name;
        this._onFrameLabel(label);
    },
    _onFrameLabel(label) {
        // 处理位移
        if (this.tweenMoves.length !== 0) {
            switch (label) {
                case 'noMove':
                    this.tweenMoves.forEach(tm => tm.pauseTween());
                    break;
                case 'move':
                    this.tweenMoves.forEach(tm => tm.resumeTween());
                    break;
            }
        }
        // 调用子类可能重写的方法
        this.onFrameLabel(label);
        // 发送事件
        cc.Component.EventHandler.emitEvents(this.labelEvents, new cc.Event.EventCustom('animLabel'), this, label);
    },
    _onComplete() {
        // 发送事件
        cc.Component.EventHandler.emitEvents(this.completeEvents, new cc.Event.EventCustom('animComplete'), this);
    },
    _getTarget(){
        this.target = this.target || this.node.getComponent(dragonBones.ArmatureDisplay);
        return this.target;
    },
});
